src\index.js
import React, { Component } from 'react'
import ReactDOM from 'react-dom';
import App from './components/App'
ReactDOM.render(<App />, document.querySelector('#root'));
src\apis\youtube.js
import axios from 'axios';
const KEY = '請輸入你自己申請的API KEY'
export default axios.create({
baseURL: 'https://www.googleapis.com/youtube/v3',
params: {
part: 'snippet',
type: 'video',
maxResults: 5,
key: KEY
},
})
src\components\App.js
import React, { useState, useEffect } from 'react'
import SearchBar from './SearchBar'
import youtube from '../apis/youtube'
import VideoList from './VideoList'
import VideoDetail from './VideoDetail'
const App = () => {
const [videos, setVideos] = useState([])
const [selectedVideo, setSelectedVideo] = useState(null)
useEffect(() => {
onTermSubmit('cat')
}, [])
const onTermSubmit = async (term) => {
// console.log(term)
const res = await youtube.get('/search', {
params: {
q: term
}
})
setVideos(res.data.items)
setSelectedVideo(res.data.items[0])
}
return (
<div className='ui container'>
<SearchBar onFormSubmit={onTermSubmit} />
{/* I have {this.state.videos.length} videos. */}
<div className="ui grid">
<div className="ui row">
<div className='eleven wide column'>
<VideoDetail video={selectedVideo} />
</div>
<div className='five wide column'>
<VideoList
onVideoSelect={setSelectedVideo}
videos={videos} />
</div>
</div>
</div>
</div>
)
}
export default App
src\components\SearchBar.js
// import React, { Component } from 'react'
import React, { useState } from 'react'
const SearchBar = ({ onFormSubmit }) => {
const [term, setTerm] = useState('')
// const onInputChange = (e) => {
// setTerm(e.target.value)
// }
const onSubmit = (e) => {
e.preventDefault();
onFormSubmit(term)
}
return (
<div className="search-bar ui segment">
<form onSubmit={onSubmit} className="ui form">
<div className="field">
<label>Video Search</label>
<input type="text"
onChange={(e) => setTerm(e.target.value)}
value={term}
/>
</div>
</form>
</div>
)
}
export default SearchBar
src\components\VideoDetail.js
import React from 'react'
const VideoDetail = ({ video }) => {
if (!video) {
return false
}
const videoSrc = `https://www.youtube.com/embed/${video.id.videoId}`
return (
<div>
<div className="ui embed">
<iframe title="video player" src={videoSrc}></iframe>
</div>
<div className='ui segment' >
<h4 className="ui header">{video.snippet.title}</h4>
<p>{video.snippet.description}</p>
</div>
</div>
)
}
export default VideoDetail
src\components\Videoitem.css
.video-item {
display: flex !important;
align-items: center !important;
cursor: pointer;
}
.video-item.item img {
max-width: 180px;
}
src\components\VideoItem.js
import './VideoItem.css'
import React from 'react'
const VideoItem = ({ video, onVideoSelect }) => {
return (
<div onClick={() => { onVideoSelect(video) }} className='video-item item'>
<img alt={video.snippet.title} className='ui image' src={video.snippet.thumbnails.medium.url} />
<div className='content' >
<div className="header">
{video.snippet.title}
</div>
</div>
</div>
)
}
export default VideoItem
src\components\ VideoList.js
import React from 'react'
import VideoItem from './VideoItem'
const VideoList = ({ videos, onVideoSelect }) => {
const renderList = videos.map((video) => {
return (
<VideoItem key={video.id.videoId} onVideoSelect={onVideoSelect} video={video} />
)
})
return (
<div className='ui relaxed divided list' >{renderList}</div>
)
}
export default VideoList
[Let's Test Your React Mastery])(https://github.com/yichern/modern-react-with-redux)